<?php
require_once "class.FPDF.php";

class ovfPdf extends FPDF {

public $usedWidth = 0;
public $usedHeight = 0;
public $topMargin = 25;
public $bottomMargin = 20;
public $leftMargin = 20;
public $rightMargin = 20;
public $topLeftText = '';
public $topRightImage = null;
public $bottomLeftText = '';
public $bottomMiddleText = '';
public $outlines=array();
public $OutlineRoot;

public $widths;
public $aligns;
public $styles;
public $bgColors;
public $borders;


public function __constructor($aOpt=array()) {
	$this->topMargin = (isset($aOpt['topMargin']))?intval($aOpt['topMargin']):25;
	$this->bottomMargin = (isset($aOpt['bottomMargin']))?intval($aOpt['bottomMargin']):20;
	$this->leftMargin = (isset($aOpt['leftMargin']))?intval($aOpt['leftMargin']):20;
	$this->rightMargin = (isset($aOpt['rightMargin']))?intval($aOpt['rightMargin']):20;
	parent::__construct();
}
/**
 * AddPage - aggungi pagina
 * otrientation: P = portatrait , L = laldscape - default = precedente o P
 * impostare proprieta'
 * 	topLeftText
 * 	topRightImage 
 * 	bottomLeftText
 * 	bottomMiddleText
 */
public function AddPage($orientation='') {
	$this->AliasNbPages();
	$this->SetMargins($this->leftMargin,$this->topMargin,$this->rightMargin);
	$this->SetAutoPageBreak(true,$this->bottomMargin);
	parent::AddPage($orientation);
	$this->usedWidth = $this->w - $this->lMargin - $this->rMargin;
	$this->usedHeight = $this->h - $this->tMargin - $this->bMargin;
}

/**
 * imposta il logo in alto a destra
 * @return bool
 */
private function setLogo() {
	global $objSess, $objDB;
	$this->topRightImage = null;
	$sNF = "logo_pdf";
	$filePath = OVF_FS_WEB_ROOT.'/pers/logoAzienda50.jpg';
	list($width, $height) = getimagesize($filePath);
	$xLogo = $this->w - $this->rMargin - ($width * 10 / $height);
	$yLogo = $this->tMargin - 15.5;
	$this->Image($filePath, $xLogo, $yLogo,0,10);
	return true;
}

public function Header() {
	$x1 = $this->lMargin;
	$x2 = $this->w - $this->rMargin;
	$y = $this->tMargin - 5;
	$this->SetDrawColor(0,0,0);
	$this->SetFont('arial','',12);
	$this->SetTextColor(0,0,0);
	$this->Line($x1,$y,$x2,$y);
   $this->SetY(18);
	$this->Cell(0,0,$this->topLeftText,0,0,'');	
	$this->setLogo();
	$this->SetY($this->tMargin);
	
}

public function Footer() {
	$x1 = $this->lMargin;
	$x2 = $this->w - $this->rMargin;
	$y = $this->h - $this->bMargin + 5;
	$this->SetDrawColor(0,0,0);
	$this->Line($x1,$y,$x2,$y);
   $this->SetY(-13);
   $this->SetFont('arial','I',8);
	$this->SetTextColor(0,0,0);
	$this->Cell(0,0,$this->bottomLeftText,0,0,'');	
	$this->SetX(0);
	$this->Cell(0,0,$this->bottomMiddleText,0,0,'C');	
   $this->Cell(0,0,'Pagina '.$this->PageNo().' di {nb}',0,0,'R');
}

private function Polygon($points, $style='D') {
    //Draw a polygon
    if($style=='F')
        $op='f';
    elseif($style=='FD' or $style=='DF')
        $op='b';
    else
        $op='s';

    $h = $this->h;
    $k = $this->k;

    $points_string = '';
    for($i=0; $i<count($points); $i+=2){
        $points_string .= sprintf('%.2f %.2f', $points[$i]*$k, ($h-$points[$i+1])*$k);
        if($i==0)
            $points_string .= ' m ';
        else
            $points_string .= ' l ';
    }
    $this->_out($points_string . $op);
}

/**
 * SetFillColN
 * setta colori riempimento in base a codice HTML
 */
public function SetFillColN($c) {
	$c1 = hexdec (substr($c,0,2));
	$c2 = hexdec (substr($c,2,2));
	$c3 = hexdec (substr($c,4,2));
	$this->SetFillColor($c1,$c2,$c3);
}

/**
 * SetDrawColN
 * setta colori disegno in base a codice HTML
 */
public function SetDrawColN($c) {
	$c1 = hexdec (substr($c,0,2));
	$c2 = hexdec (substr($c,2,2));
	$c3 = hexdec (substr($c,4,2));
	$this->SetDrawColor($c1,$c2,$c3);
}

/**
 * SetTextColN
 * setta colori testo in base a codice HTML
 */
public function SetTextColN($c) {
	$c1 = hexdec (substr($c,0,2));
	$c2 = hexdec (substr($c,2,2));
	$c3 = hexdec (substr($c,4,2));
	$this->SetTextColor($c1,$c2,$c3);
}

/**
 * SetXN
 * analogo a SETX
 * $X = posizione orizzontale (da 1 a 20)
 */
public function SetXN($X) {
	if ($X >0 and $X < 21) {
		$xconv = $this->usedWidth / 20;
		$xr = ($X-1)*$xconv + $this->lMargin;
		$this->SetX($xr);
	}
}

/**
 * SetYN
 * analogo a SETY
 * $Y = posizione verticale (da 1 a 20)
 */
public function SetYN($Y) {
	if ($Y > 0 and $Y < 21) {
		$yconv = $this->usedHeight / 20;
		$yr = ($Y-1)*$yconv + $this->tMargin;
		$this->SetY($yr);
	}
}

/**
 * RectN
 * Rettangolo
 * $X = posizione orizzontale (da 1 a 20)
 * $Y = posizione verticale (da 1 a 20)
 * $W = larghezza (da 0 a 20)
 * $H = altezza (da 0 a 20)
 * $stile - vedi metodo Rect
 */
public function RectN($X, $Y, $W, $H, $stile) {
	$xconv = $this->usedWidth / 20;
	$xr = ($X-1)*$xconv + $this->lMargin;
	$wr = $W * $xconv;
	$yconv = $this->usedHeight / 20;
	$yr = ($Y-1)*$yconv + $this->tMargin;
	$hr = $H * $yconv;
	$this->Rect($xr,$yr,$wr,$hr,$stile);
}

/**
 * Testo
 * Tseto multiriga
 * $X = posizione orizzontale (da 1 a 20)
 * $W = larghezza (da 0 a 20)
 * $testo = testo
 * $aOpt = array opzioni
 * 		'align' = 'J'- justificato, 'C' - centrato, 'R' - a destra, 'L' - a sinistra
 */

public function Testo($X, $W, $testo, $aOpt=null) {
	$xconv = $this->usedWidth / 20;
	$xr = ($X-1)*$xconv + $this->lMargin;
	$wr = ($W)*$xconv;
	$this->SetX($xr);
	$align = (isset($aOpt['align']))?$aOpt['align']:'J';
	$this->MultiCell($wr,$this->FontSize,$testo,0,$align);	
}

/**
 * TestoTabella
 * Tabella di testi multiriga
 * $X = posizione orizzontale (da 1 a 20)
 * $W = larghezza (da 0 a 20)
 * $aTesti = array righe, colonne. Ogni elementomcontirne un array associativo:
 * 	'text' = testo
 * 	'aOpt' = array opzioni
 * 		'align' = 'J'- justificato, 'C' - centrato, 'R' - a destra, 'L' - a sinistra
 * 		'size' = punti carattere
 * 		'style' = 'B' - bold, ''- normale, 'I'- corsivo
 * $aWidthCol = array con tanti elementi quante sono le colonne
 *       la dimensione delle colonne e' proporzionale ai numeri dxell'array
 */
public function TestoTabella($X, $W, $aTesti, $aWidthCol) {
	$numCol = count($aWidthCol);
	$aTotWidth = 0;
	foreach($aWidthCol as $k => $c) {$aTotWidth += $c;}
	foreach($aWidthCol as $k => $c) {$aWidthCol[$k] = $c/$aTotWidth;}
	$xconv = $this->usedWidth / 20;
	$xr1 = ($X-1)*$xconv + $this->lMargin;
	$wr = ($W)*$xconv;
	$this->SetX($xr1);
	$this->setDrawColN('000000');
	if (($this->usedHeight - $this->GetY()) < 10) {
		$this->AddPage();
	}
	foreach($aTesti as $kRig => $aRiga) {
		if (($this->usedHeight - $this->GetY()) < 10) {
			$yr1 = $this->GetY();
			$this->Line($xr1,$yr1,$xr1+$wr,$yr1); //linea orizz superiore
			$this->AddPage();
		}
		$yr1 = $yr2 = $this->GetY();
		$xr2 = $xr1;
		for($kCol = 0; $kCol < $numCol; $kCol++) {
			$testo = (isset($aRiga[$kCol]['text']))?$aRiga[$kCol]['text']:'';
			$align = (isset($aRiga[$kCol]['aOpt']['align']))?$aRiga[$kCol]['aOpt']['align']:'J';
			$size = (isset($aRiga[$kCol]['aOpt']['size']))?$aRiga[$kCol]['aOpt']['size']:10;
			$style = (isset($aRiga[$kCol]['aOpt']['style']))?$aRiga[$kCol]['aOpt']['style']:'';
			$this->setY($yr1+1);
			$this->setX($xr2+1);
			$this->setFont('arial',$style,$size);
			$this->MultiCell($aWidthCol[$kCol]*$wr-2,$this->FontSize+1,$testo,0,$align);	
			$xr2 += $aWidthCol[$kCol]*$wr;
			$newY = $this->GetY()+1;
			$this->setY($newY);
			if ($yr2 < $newY) $yr2 = $newY;
		}
		$this->Line($xr1,$yr1,$xr1+$wr,$yr1); //linea orizz superiore
		$this->Line($xr1,$yr1,$xr1,$yr2); //prima linea vert di cella
		$xr2 = $xr1;
		foreach($aWidthCol as $KCol => $width) {
			$xr2 += $width*$wr;
			$this->Line($xr2,$yr1,$xr2,$yr2); //line vert di cella
		}
		$this->setY($yr2);
	}
	$this->Line($xr1,$yr2,$xr1+$wr,$yr2); // linea orizz finale
}

/**
 * Prisma - disegna un prisma
 * x1,y1 = angolo basso sinistra
 * h = altezza, w = larghezza, p=prospettiva
 * c0=colore bordo, c1=colore fonte, c1=colore lato, c1=colore sopra
 */

private function Prisma($x1,$y1,$h,$w,$p,$c1) {
	$x2=$x1+$w;
	$y2=$y1-$h;
	$c1R = hexdec(substr($c1,0,2));
	$c1G = hexdec(substr($c1,2,2));
	$c1B = hexdec(substr($c1,4,2));
	$c2R = ($c1R > 16)?$c1R-16:0;
	$c2G = ($c1G > 16)?$c1G-16:0;
	$c2B = ($c1B > 16)?$c1B-16:0;
	$c3R = ($c2R > 16)?$c2R-16:0;
	$c3G = ($c2G > 16)?$c2G-16:0;
	$c3B = ($c2B > 16)?$c2B-16:0;
	// davanti
	$this->SetFillColor($c1R,$c1G,$c1B);
	$this->Rect($x1,$y1-$h,$w,$h,'F');
	// sopra
	if ($h < 0) {
		$this->SetFillColN('888888');
		$this->Polygon(array($x1,$y1,$x1+$p,$y1-$p,$x2+$p,$y1-$p,$x2,$y1),'F');		
	} else {
		$this->SetFillColor($c2R,$c2G,$c2B);
		$this->Polygon(array($x1,$y2,$x1+$p,$y2-$p,$x2+$p,$y2-$p,$x2,$y2),'F');
	}
	// destra
	$this->SetFillColor($c3R,$c3G,$c3B);
	$this->Polygon(array($x2,$y1,$x2,$y2,$x2+$p,$y2-$p,$x2+$p,$y1-$p),'F');
}

/**
 * Grafico
 * $X = posizione orizzontale (da 1 a 20)
 * $Y = posizione verticale (da 1 a 20)
 * $W = larghezza (da 0 a 20)
 * $H = altezza (da 0 a 20)
 * $aVal = valori - array associativo:
 * 	grafico di nx valori di ascissa e ny valori di ordinata
 * 	'gtit' = titolo
 * 	'xval' = array(...nx elementi...) - descrizioni variabili x
 * 	'yfrm' = decimali valori e suffisso- es.: "2%" = 2 decimali e suffisso %
 * 	'ytit' = array(...ny elementi...) - descrizioni variabili y
 * 	'yval' = array(array(valore, ...nx elementi..), ...ny elementi... , ) - valore(y,x)
 * 	'ycol' = array(...ny elementi...) - colore formato HTML
 */
public function Grafico($X, $Y, $W, $H, $aVal) {
	$xconv = $this->usedWidth / 20;
	$yconv = $this->usedHeight / 20;
	$xr = ($X-1)*$xconv + $this->lMargin;
	$yr = ($Y-1)*$yconv + $this->tMargin;
	$hr = ($H)*$yconv;
	$wr = ($W)*$xconv;
	// bordo
	$this->SetDrawColN('888888');
	$this->rect($xr,$yr,$wr,$hr,'D');
	//titolo - tronca se supera le larghezza prevista
	$this->SetFont('arial','B',9);
	$txt = $txtIniz = $aVal['gtit'];
	$txt2 = (isset($aVal['gtit2'])) ? $aVal['gtit2'] : "";
	$ls = $this->GetStringWidth($txt);
	while($wr > 0 and $ls > $wr) {
		$txt = substr($txt,0,-1);
		if ($txt != '' and substr($txt,-1) != ' ') { continue; }
		$ls = $this->GetStringWidth($txt);
	}
	$this->text($xr+1,$yr+4,$txt);
	if ($txt2 == "") {
		if ($txt != $txtIniz) {
			$txt2 = substr($txtIniz,strlen($txt));
			$ls = $this->GetStringWidth($txt2);
			while($wr > 0 and $ls > $wr) {
				$txt2 = substr($txt2,0,-1);
				$ls = $this->GetStringWidth($txt2);
			}
			$this->text($xr+1,$yr+8,$txt2);
		}
	} else {
		$ls = $this->GetStringWidth($txt2);
		while($wr > 0 and $ls > $wr) {
			$txt2 = substr($txt2,0,-1);
			if ($txt2 != '' and substr($txt2,-1) != ' ') { continue; }
			$ls = $this->GetStringWidth($txt2);
		}
		$this->text($xr+1,$yr+8,$txt2);
	}	
	
	// parametri sfondo
	$mx = 5; //margine destro e sinistro
	$mys = 11; //margine superiore
	$myi = 8; //margine inferiore
	$p = 10; //profondita'
	// sfondo dietro
	$this->SetDrawColN('888888');
	$this->SetFillColN('E5E5E5');
	$this->rect(
		$xr+$p+$mx,$yr+$mys,
		$wr-$p-2*$mx,$hr-$p-$mys-$myi,'FD');
	// sfondo sinistra
	$this->Polygon(array(
		$xr+$mx, $yr+$hr-$myi,     //basso sinistra
		$xr+$mx, $yr+$p+$mys,         //alto sinistra
		$xr+$mx+$p,$yr+$mys,         //alto destra
		$xr+$mx+$p,$yr+$hr-$p-$myi),      //basso destra
		'FD');
	// sfondo sotto
	$this->SetFillColN('B2B2B2');
	$this->Polygon(array(
		$xr+$mx, $yr+$hr-$myi,     //basso sinistra
		$xr+$mx+$p,$yr+$hr-$p-$myi,      //alto sinistra
		$xr+$wr-$mx,$yr+$hr-$p-$myi,     //alto destra
		$xr+$wr-$p-$mx,$yr+$hr-$myi),      //basso destra
		'FD');
	$max = -999999999999999;
	$min = 999999999999999;
	$nSerie = count($aVal['yval']);
	$nVal = 0;
	foreach($aVal['yval'] as $n => $aV1) {
		foreach($aV1 as $k => $val) {
			$aVal['yval'][$n][$k] = $val = (double)$val;
			if ($k > $nVal) $nVal = $k;	
			if ($val > $max) $max = $val;	
			if ($val < $min) $min = $val;	
		}
	}
	$nVal++;
	if ($min > 0) $min = 0;
	if ($max < 0) $max = 0;
	$pg = 3;
	$pp = 10-2*$pg;
	$unita = ($max -$min)/($hr-$p-$myi-$mys);
	if ($unita == 0) $unita = 1;
	$spaz = ($wr-$p-$mx*2)/(($nVal+1)+$nVal*$nSerie);
	$larg = ((($wr-$p-$mx*2-$spaz)/$nVal)-$spaz)/$nSerie;
	
	$xp = $xr+$mx+$spaz+$pg;
	$yp = $yr+$hr-$myi-$pg;
	
	$delta = $max - $min;
	$yzero = $min * -1 / $unita;
	//prismi negativi
	for($k=0; $k<$nVal; $k++) {
		$this->SetFont('arial','',6);
		$this->SetXY($xp,$yr+$hr-$myi+2);
		$this->Cell($larg*$nSerie,0,$aVal['xval'][$k],0,0,'C');
		foreach($aVal['yval'] as $n => $aV1) {
			if ($aV1[$k] < 0) {
				$yval = $aV1[$k] / $unita;
				$this->Prisma($xp,$yp-$yzero,$yval,$larg,$pp,$aVal['ycol'][$n]);
				$this->SetFont('arial','',6);
				$this->SetXY($xp,$yp-$yzero-$yval+2);
				$this->Cell($larg+$pp,0,$this->formatN($aVal['yfrm'],$aV1[$k]),0,0,'R');
			}	
			$xp += $larg;
		}
		$xp += $spaz;
	}
	$this->SetDrawColN('888888');
	// piano zero
	if ($min != 0) {
		$this->Polygon(array(
			$xr+$mx, $yr+$hr-$myi-$yzero,     //basso sinistra
			$xr+$mx+$p,$yr+$hr-$p-$myi-$yzero,      //alto sinistra
			$xr+$wr-$mx,$yr+$hr-$p-$myi-$yzero,     //alto destra
			$xr+$wr-$p-$mx,$yr+$hr-$myi-$yzero),      //basso destra
			'D');
	}
	//prismi positivi
	$xp = $xr+$mx+$spaz+$pg;
	for($k=0; $k<$nVal; $k++) {
		foreach($aVal['yval'] as $n => $aV1) {
			if ($aV1[$k] >= 0) {
				$yval = $aV1[$k] / $unita;
				$this->Prisma($xp,$yp-$yzero,$yval,$larg,$pp,$aVal['ycol'][$n]);
				$this->SetFont('arial','',6);
				$this->SetXY($xp,$yp-$yzero-$yval-$pp-1);
				$this->Cell($larg+$pp,0,$this->formatN($aVal['yfrm'],$aV1[$k]),0,0,'R');
			}	
			$xp += $larg;
		}
		$xp += $spaz;
	}
	
	return true;
}

private function formatN($yfrm, $val) {
	return number_format($val,$yfrm[0],',','.').substr($yfrm,1);
}

/**
 * Tabella
 * X - posizione da 1 a 20 - 0 = corrente
 * Y - posizione da 1 a 20 - 0 = corrente
 * $aOpt[width] = array (lrag-1, ..., larg-n) - larghezza colonne
 * $aOpt[height-h] = height-h - altezza riga testa
 * $aOpt[height-r] = array(height-r1, ...) - altezza righe dati
 * $aOpt[style] = <codstile> => array(font-size,font-type,align,color,bgcolor)
 * $aHeader = array(testo-1, ..., testo-n) testo-x puo' essere stringa o array(testo-x,stile,colspan)
 * $aRows = array ( array(testo-1, ..., testo-n),...) testo-x puo' essere stringa o array(testo-x,stile,colspan)
 * 
 */
public function Tabella($X, $Y, $aHeaders, $aRows, $aOpt) {
	if ($X < 1 or $X > 20) {
		 $X = 1;
	}
	if (isset($aOpt['style'])) {
		foreach($aOpt['style'] as $style =>$aStyle) {
			for($k=0;$k<5;$k++) {
				if (!isset($aStyle[$k])) $aOpt['style'][$k] = '';
			}
		}
	}
	$xconv = $this->usedWidth / 20;
	$xr = ($X-1)*$xconv + $this->lMargin;
	$widthMax = (21-$X);
	if ($Y > 0 and $Y < 21) {
		$yconv = $this->usedHeight / 20;
		$yr = ($Y-1)*$yconv + $this->tMargin;
		$this->SetY($yr);
	}
	$this->SetX($xr);
	//verifica larghezze
	$aOpt['width']=array_values($aOpt['width']);
	for($k=0; isset($aOpt['width'][$k]); $k++) {
 		if ($aOpt['width'][$k] > $widthMax) $aOpt['width'][$k] = $widthMax;
 		if ($aOpt['width'][$k] <= 0) unset($aOpt['width'][$k]); 		
	}
   //Header
   $align = 'L';
   $fontStyle = 'N';
   $fontSize = 10;
   $height = 5;
   $color = '000000';
   $bgColor = 'FFFFFF';
   $this->SetDrawColN('000000');
   $this->SetTextColN($color);
   $this->SetFillColN($bgColor);
   $this->SetFont('arial',($fontStyle=='N')?'':$fontStyle,$fontSize);
   $j = 0;
   for($k=0; $k<count($aOpt['width']); $k++) {
   	$width = $aOpt['width'][$k];
   	$height = (isset($aOpt['height-h']))?0+$aOpt['height-h']:5;
    	$aText = (isset($aHeaders[$j]))?$aHeaders[$j]:'';
    	if (is_array($aText)) {
	    	$text = (isset($aText[0]))?$aText[0]:'';
    		$style = (isset($aText[1]))?$aText[1]:'';
    		if (isset($aOpt['style'][$style])) {
    			$fontSize  = ($aOpt['style'][$style][0]=='')?$fontSize :$aOpt['style'][$style][0];
    			$fontStyle = ($aOpt['style'][$style][1]=='')?$fontStyle:$aOpt['style'][$style][1];
    			$fontStyle = (preg_match("/[^BI]/",$fontStyle))?'':$fontStyle;
    			$align     = ($aOpt['style'][$style][2]=='')?$align    :$aOpt['style'][$style][2];
    			$color     = ($aOpt['style'][$style][3]=='')?$color    :$aOpt['style'][$style][3];
    			$bgColor   = ($aOpt['style'][$style][4]=='')?$bgColor  :$aOpt['style'][$style][4];
			   $this->SetTextColN($color);
			   $this->SetFillColN($bgColor);
			   $this->SetFont('arial',$fontStyle,(float)$fontSize);
			   //$fontSize = (float)$fontSize;
			   //$this->SetFontSize($fontSize);
			   //$text .= "($fontSize-$fontStyle)";
    		}
    		$colspan = (isset($aText[2]))?$aText[2]:1;
    		$colspan--;
    		while($colspan > 0) {
    			$colspan--;
    			$k++;
    			if (isset($aOpt['width'][$k])) $width += $aOpt['width'][$k];
    		}
    	} else {
    		$text = $aText;
    	} 
      $this->CellX($width*$xconv,$height,$text,1,0,$align,1);
      $j++;
   }
   $this->Ln();
   //Data
   $align = 'L';
   $fontStyle = 'N';
   $fontSize = 10;
   $color = '000000';
   $bgColor = 'FFFFFF';
   $this->SetTextColN($color);
   $this->SetFillColN($bgColor);
   $this->SetFont('arial',($fontStyle=='N')?'':$fontStyle,$fontSize);
   foreach($aRows as $kRow => $row) {
		$this->SetX($xr);
		$j = 0;
	   for($k=0; $k<count($aOpt['width']); $k++) {
	    	$width = $aOpt['width'][$k];
	    	if (isset($aOpt['height-r'][$kRow])) $height = 0+$aOpt['height-r'][$kRow];
	    	if (isset($row[$j])) {
	    		$aText = $row[$j];
	    	} else {
	    		if (isset($aOpt['styledef'])) {
	    			$aText = array('',$aOpt['styledef']);
	    		} else {
	    			$aText = '';
	    		}
	    	}
	    	if (is_array($aText)) {
	    		$text = (isset($aText[0]))?$aText[0]:'';
	    		$style = (isset($aText[1]))?$aText[1]:'';
	    		if (isset($aOpt['style'][$style])) {
	    			$fontSize  = ($aOpt['style'][$style][0]=='')?$fontSize :$aOpt['style'][$style][0];
	    			$fontStyle = ($aOpt['style'][$style][1]=='')?$fontStyle:$aOpt['style'][$style][1];
	    			$fontStyle = (preg_match("/[^BI]/",$fontStyle))?'':$fontStyle;
	    			$align     = ($aOpt['style'][$style][2]=='')?$align    :$aOpt['style'][$style][2];
	    			$color     = ($aOpt['style'][$style][3]=='')?$color    :$aOpt['style'][$style][3];
	    			$bgColor   = ($aOpt['style'][$style][4]=='')?$bgColor  :$aOpt['style'][$style][4];
				   $this->SetTextColN($color);
				   $this->SetFillColN($bgColor);
			   	$this->SetFont('helvetica',$fontStyle,(float)$fontSize);
	    		}
	    		$colspan = (isset($aText[2]))?$aText[2]:1;
	    		$colspan--;
	    		while($colspan > 0) {
	    			$colspan--;
	    			$k++;
	    			if (isset($aOpt['width'][$k])) $width += $aOpt['width'][$k];
	    		}
	    	}  else {
	    		$text = $aText;
	    	}
	      $this->CellX($width*$xconv,$height,$text,1,0,$align,1);
	      $j++;
	   }
	   $this->Ln();
   }
}

/**
 * CellX
 * come Cell ma trinca testo se supera dimensioni
 */
private function CellX($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='') {
	$ls = $this->GetStringWidth($txt);
	while($w > 0 and $ls > $w) {
		if ($align=='R') {
			$txt = substr($txt,1);
		} else {
			$txt = substr($txt,0,-1);
		}
		$ls = $this->GetStringWidth($txt);
	}
	$this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link);
}

/**
 * Bookmark
 * Imposta un bookmarlk alla posizione corrente 
 */ 

function Bookmark($txt,$level=0,$y=0)
{
    if($y==-1)
        $y=$this->GetY();
    $this->outlines[]=array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->PageNo());
}

function _putbookmarks()
{
    $nb=count($this->outlines);
    if($nb==0)
        return;
    $lru=array();
    $level=0;
    foreach($this->outlines as $i=>$o)
    {
        if($o['l']>0)
        {
            $parent=$lru[$o['l']-1];
            //Set parent and last pointers
            $this->outlines[$i]['parent']=$parent;
            $this->outlines[$parent]['last']=$i;
            if($o['l']>$level)
            {
                //Level increasing: set first pointer
                $this->outlines[$parent]['first']=$i;
            }
        }
        else
            $this->outlines[$i]['parent']=$nb;
        if($o['l']<=$level and $i>0)
        {
            //Set prev and next pointers
            $prev=$lru[$o['l']];
            $this->outlines[$prev]['next']=$i;
            $this->outlines[$i]['prev']=$prev;
        }
        $lru[$o['l']]=$i;
        $level=$o['l'];
    }
    //Outline items
    $n=$this->n+1;
    foreach($this->outlines as $i=>$o)
    {
        $this->_newobj();
        $this->_out('<</Title '.$this->_textstring($o['t']));
        $this->_out('/Parent '.($n+$o['parent']).' 0 R');
        if(isset($o['prev']))
            $this->_out('/Prev '.($n+$o['prev']).' 0 R');
        if(isset($o['next']))
            $this->_out('/Next '.($n+$o['next']).' 0 R');
        if(isset($o['first']))
            $this->_out('/First '.($n+$o['first']).' 0 R');
        if(isset($o['last']))
            $this->_out('/Last '.($n+$o['last']).' 0 R');
        $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]',1+2*$o['p'],($this->h-$o['y'])*$this->k));
        $this->_out('/Count 0>>');
        $this->_out('endobj');
    }
    //Outline root
    $this->_newobj();
    $this->OutlineRoot=$this->n;
    $this->_out('<</Type /Outlines /First '.$n.' 0 R');
    $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
    $this->_out('endobj');
}

function _putresources()
{
    parent::_putresources();
    $this->_putbookmarks();
}

function _putcatalog()
{
    parent::_putcatalog();
    if(count($this->outlines)>0)
    {
        $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
        $this->_out('/PageMode /UseOutlines');
    }
}

/**
 * CreateIndex
 * Crea il sommario in base ai bookmark creati
 */
function CreateIndex(){
    //Index title
    $this->SetFont('arial','',20);
    $this->Bookmark('Indice');
    $this->Cell(0,5,'Indice',0,1,'C');
    $this->SetFont('arial','',12);
    $this->Ln(10);

    $size=sizeof($this->outlines);
    $PageCellSize=$this->GetStringWidth('p. '.$this->outlines[$size-1]['p'])+2;
    for ($i=0;$i<$size;$i++){
        //Offset
        $level=$this->outlines[$i]['l'];
        if($level>0)
            $this->Cell($level*8);

        //Caption
        $str=$this->outlines[$i]['t'];
        $strsize=$this->GetStringWidth($str);
        $avail_size=$this->w-$this->lMargin-$this->rMargin-$PageCellSize-($level*8)-4;
        while ($strsize>=$avail_size){
            $str=substr($str,0,-1);
            $strsize=$this->GetStringWidth($str);
        }
        $this->Cell($strsize+2,$this->FontSize+2,$str);

        //Filling dots
        $w=$this->w-$this->lMargin-$this->rMargin-$PageCellSize-($level*8)-($strsize+2);
        $nb=$w/$this->GetStringWidth('.');
        $dots=str_repeat('.',$nb);
        $this->Cell($w,$this->FontSize+2,$dots,0,0,'R');

        //Page number
        $this->Cell($PageCellSize,$this->FontSize+2,'p. '.$this->outlines[$i]['p'],0,1,'R');
    }
}

// metodi per metodo row

function SetBorders($brd)
{
	//Set the array of column bgColors
	$this->borders=$brd;
}

function SetBgColors($bg)
{
	//Set the array of column bgColors
	$this->bgColors=$bg;
}

function SetWidths($w)
{
	//Set the array of column widths
	$this->widths=$w;
}

function SetAligns($a)
{
	//Set the array of column alignments
	$this->aligns=$a;
}

function SetStyles($a)
{
	//Set the array of column alignments
	$this->styles=$a;
}

function Row($data)
{
	//Calculate the height of the row
	$hRiga = $this->FontSizePt / 2;
	$nb=0;
	for($i=0;$i<count($data);$i++)
		$nb=max($nb,$this->NbLines($this->widths[$i],$data[$i]));
	$h=$hRiga*$nb;
	//Issue a page break first if needed
	$bNewPag = $this->CheckPageBreak($h);
	//Draw the cells of the row
	for($i=0;$i<count($data);$i++)
	{
		$w=$this->widths[$i];
		$a=isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
		if (isset($this->styles[$i])) {
			$this->setFont('',$this->styles[$i],$this->FontSizePt);
		} else {
			$this->setFont('','',$this->FontSizePt);
		}
		if (is_array($this->bgColors[$i])) {
			$this->SetFillColor($this->bgColors[$i][0],$this->bgColors[$i][1],$this->bgColors[$i][2]);
		} else {
			$this->SetFillColor(255,255,255);
		}
		//Save the current position
		$x=$this->GetX();
		$y=$this->GetY();
		//Draw the border
		$this->Rect($x,$y,$w,$h,'DF');
		/*////
		$bordi = (isset($this->borders[$i]))?str_pad($this->borders[$i],"S",4):'SSSS';
		if ($bordi[0]!='N' or $bNewPag) $this->Line($x,$y,$x+$w,$y); 			//top
		if ($bordi[1]!='N') $this->Line($x+$w,$y,$x+$w,$y+$h);	//right
		if ($bordi[2]!='N') $this->Line($x,$y+h,$x+$w,$y+h);		//bottom
		if ($bordi[3]!='N') $this->Line($x,$y,$x,$y+$h);			//left
		//*////
		//Print the text
		$this->MultiCell($w,$hRiga,$data[$i],0,$a);
		//Put the position to the right of the cell
		$this->SetXY($x+$w,$y);
	}
	//Go to the next line
	$this->Ln($h);
}

function CheckPageBreak($h)
{
	//If the height h would cause an overflow, add a new page immediately
	if($this->GetY()+$h>$this->PageBreakTrigger) {
		$this->AddPage($this->CurOrientation);
		return true;
	}
	return false;
}

function NbLines($w,$txt)
{
	//Computes the number of lines a MultiCell of width w will take
	$cw=&$this->CurrentFont['cw'];
	if($w==0)
		$w=$this->w-$this->rMargin-$this->x;
	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
	$s=str_replace("\r",'',$txt);
	$nb=strlen($s);
	if($nb>0 and $s[$nb-1]=="\n")
		$nb--;
	$sep=-1;
	$i=0;
	$j=0;
	$l=0;
	$nl=1;
	while($i<$nb)
	{
		$c=$s[$i];
		if($c=="\n")
		{
			$i++;
			$sep=-1;
			$j=$i;
			$l=0;
			$nl++;
			continue;
		}
		if($c==' ')
			$sep=$i;
		$l+=$cw[$c];
		if($l>$wmax)
		{
			if($sep==-1)
			{
				if($i==$j)
					$i++;
			}
			else
				$i=$sep+1;
			$sep=-1;
			$j=$i;
			$l=0;
			$nl++;
		}
		else
			$i++;
	}
	return $nl;
}

} //fine classe ovfPdf
?>